var map             = false,
   clickmarker,
   infowindow      = new google.maps.InfoWindow(),
   geocoder        = new google.maps.Geocoder(),
   default_icon    = '/public/assets/images/icons/map-marker.png',
   map_container   = 'map_canvas',
   default_lat     = 10.823099,
   default_lng     = 106.629664,
   center_icon     = '/public/assets/images/icons/center-map-marker.png';
   
function make_icon(src, w, h) {
    return new google.maps.MarkerImage(src,
    null, null, null, new google.maps.Size(w, h))
}    

function google_map (ops, callback) {
   var w, h, icon = '',
       zoom        = 14,
       lat_lng     = new google.maps.LatLng(ops.latitude, ops.longitude),
       options     = {
           zoom: zoom,
           minZoom: 14,
           center: lat_lng,
           mapTypeId: google.maps.MapTypeId.ROADMAP
       }
   w = typeof(ops.w) != 'undefined' ? ops.w : 18,
   h = typeof(ops.w) != 'undefined' ? ops.h : 28;
   icon = make_icon(typeof(ops.src_icon) != 'undefined' ? ops.src_icon : default_icon, w, h);
   map = new google.maps.Map(document.getElementById(map_container), options);
   clickmarker = new google.maps.Marker ({
           position: lat_lng,
           map: map,
           draggable: typeof(ops.draggable) != 'undefined' ? ops.draggable : true,
           icon: icon
   });
 
   infowindow = new google.maps.InfoWindow({
       content: ops.html
   });  
   
   // For the direction setting
   directionsService = new google.maps.DirectionsService();
   directionsDisplay = new google.maps.DirectionsRenderer({map: map})
   
   //Handler click event in marker
   google.maps.event.addListener( clickmarker, 'click', function() {
       infowindow.content = ops.html;
       infowindow.open(map, clickmarker);
   });
   
   //Handler finished load map
   google.maps.event.addListener(map, 'idle', function(event) {
       if (typeof(callback) != 'undefined') {
           callback({
               min_max: get_bounds(map),
               success: true
           });
       }
   });
   
   google.maps.event.addListener(clickmarker, 'dragstart', function() {
       //infowindow.close();
   });
   
   //Get location of
   google.maps.event.addListener(clickmarker, 'dragend', function (event) {
       
   });
}

//Search address of google
function search_address_gmap(address_name, ops, callback) {
   geocoder.geocode({address: address_name}, function(results, status) {

       if (status == google.maps.GeocoderStatus.OK) {
           var first_result    = results[0],
               location        = first_result.geometry.location;
         
           //Set new location
           set_position({
               location: location,
               html: first_result.formatted_address,
               src_icon: center_icon,
               w: ops.w,
               h: ops.h
           });
           
           callback({
               lng: location.lng(),
               lat: location.lat(),
               location_name: first_result.formatted_address,
               success: true,
               location: results[0]
           });
           
       } else {
           callback({success: false});
       }
   });
}

function set_position(ops) {
    map.setCenter(ops.location);
   
   //Close tooltip if existed
   if (infowindow) {
       infowindow.close()
   }

   //Close marker if existed
   if (clickmarker) {
       clickmarker.setVisible(false)
   }

   if (! map) {
       map = new google.maps.Map(document.getElementById(map_container), options);
   }
   
   clickmarker = new google.maps.Marker({
      map: map,
      icon: make_icon(typeof(ops.src_icon) != 'undefined' ? ops.src_icon : default_icon, ops.w, ops.h),
      draggable: typeof(ops.draggable) != 'undefined' ? ops.draggable : true
   })

   //Set new location
   clickmarker.setPosition(ops.location);
   infowindow = new google.maps.InfoWindow();
   
   infowindow.setContent(ops.html);
   infowindow.open(map, clickmarker);
   google.maps.event.addListener(clickmarker, 'dragstart', function() {
       //infowindow.close();
   });
   google.maps.event.addListener(clickmarker, 'dragend', function(event) {
       
   });
   
}

function get_lat_lng (lat, lng) {
   return new google.maps.LatLng(lat, lng);
}

//Do not know location
function set_current_location (callback) {
   var check = navigator.geolocation.getCurrentPosition(function (position) {
	   
       var pos = position.coords;  
       geocoder.geocode({ 'latLng': get_lat_lng(pos.latitude, pos.longitude) }, function(results, status) {
            google_map({html: 'Unknown', latitude: pos.latitude, 
                longitude: pos.longitude,
                src_icon: center_icon 
            });
       })
       
       if (callback != undefined) {
            callback({
                success: true,
                lat: pos.latitude,
                lng: pos.longitude,
            });
       }
   });
   
   if (check == undefined) {
      google_map({latitude: default_lat, longitude: default_lng}, function (res) {
    	  callback({
    		  success: false,
    	  })
      });
   }
}

function set_marker(lat, lng, link, html, src) {
    var bounds = new google.maps.LatLngBounds(),
        image  = make_icon(src != undefined ? src : default_icon, 18, 28),
        pos    = new google.maps.LatLng(lat, lng),
        marker;   
        
        bounds.extend(pos);
        
        marker = new google.maps.Marker({
           position: pos,
           map: map,
           icon: image,
           title: 'marker',
           optimized: false, // To set border radius in css of img
           url: link

       })
       
       var infowindow = new google.maps.InfoWindow();
       
       google.maps.event.addListener(marker, 'click', (function(marker, i) {
           infowindow.setContent(html);
            infowindow.open(map, marker);
            return function() {
                //window.location = marker.url
            }
       })(marker));
   }

function set_places_marker(data, map, callback) {
    var i, item, url;
      
    if (data != undefined) {
        for (i = 0; i < data.length; i++) {
            item = data[i];
            url = '#';
            set_marker(item.latitude, item.longitude, url)
        }
    }
    if (typeof (callback) != 'undefined') {
       callback({success: true})
    }
//   
//   //Set default marker for current user in dashboard
//   if (player == 1 && typeof(current_user_login) != 'undefined') {
//       action_set(localStorage.user_lat, localStorage.user_lng, current_user_login.image,
//           '#/user-profile/'+ current_user_login.id, 42, 42);
//   }
}

/**
* Get max min of map
* */
function get_bounds(map) {
   var bounds  = map.getBounds(),
       ne      = bounds.getNorthEast(), // top-left
       sw      = bounds.getSouthWest(),
       _return = ''; // bottom-right
   
    _return = {
       min_lat: sw.lat(),
       max_lat: ne.lat(),
       min_lng: sw.lng(),
       max_lng: ne.lng()
   };
   
   return _return;
}

var directionsDisplay,
	directionsService,
	stepDisplay,
	markerArray = [];
function calc_route(start, end, callback) { 
    var request = {
        origin: start,
        destination: end,
        travelMode: google.maps.TravelMode.DRIVING
    };

    // Route the directions and pass the response to a
    // function to create markers for each step.
    directionsService.route(request, function(response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
          //var warnings = document.getElementById("warnings_panel");
          //warnings.innerHTML = "" + response.routes[0].warnings + "";
          directionsDisplay.setDirections(response);
          //showSteps(response);
        }
    });
}

function showSteps(directionResult) {
  // For each step, place a marker, and add the text to the marker's
  // info window. Also attach the marker to an array so we
  // can keep track of it and remove it when calculating new
  // routes.
  var myRoute = directionResult.routes[0].legs[0];

  for (var i = 0; i < myRoute.steps.length; i++) {
      var marker = new google.maps.Marker({
        position: myRoute.steps[i].start_point,
        map: map
      });
      attachInstructionText(marker, myRoute.steps[i].instructions);
      markerArray[i] = marker;
  }
}

function attachInstructionText(marker, text) {
  google.maps.event.addListener(marker, 'click', function() {
    infowindow.setContent(text);
    infowindow.open(map, marker);
  });
}

function get_address(lat, lng, callback) {
    var lat_lng = new google.maps.LatLng(lat, lng);
    geocoder.geocode({latLng:lat_lng},function(data,status){

        callback({
            'address': status == google.maps.GeocoderStatus.OK ? data[1].formatted_address : ''
        });

    })
}

function measure(lat1, lon1, lat2, lon2){  // generally used geo measurement function
    var R = 6378.137; // Radius of earth in KM
    var dLat = (lat2 - lat1) * Math.PI / 180;
    var dLon = (lon2 - lon1) * Math.PI / 180;
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
    Math.sin(dLon/2) * Math.sin(dLon/2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var d = R * c;
    return d.toFixed(3); // km
}
